import axios from 'axios'
import jsCookie from 'js-cookie'
import { Notification, Message } from 'element-ui'
import qs from 'qs'

const instance = axios.create()
const { CancelToken } = axios

class BlogAxios {
  constructor () {
    this.interceptors(instance) // 绑定拦截器
    this.request = this.request.bind(this)
    this.sourceToken = {}
  }

  // 发送请求
  request (options) {
    let assignOpts

    this.cancel(options.url)
    const source = CancelToken.source()
    //, cancelToken: source.token
    assignOpts = { ...getConfig(), ...options }
    this.sourceToken[options.url] = source.cancel

    return instance(assignOpts)
  }

  cancel (url) {
    Boolean(this.sourceToken[url]) && this.sourceToken[url]()
  }

  // 拦截器
  interceptors (instance) {
    // 拦截请求
    instance.interceptors.request.use(config => {
      if (config.method === 'get') {
        // 如果是get请求，且params是数组类型如arr=[1,2]，则转换成arr=1&arr=2
        config.paramsSerializer = function (params) {
          return qs.stringify(params, {arrayFormat: 'repeat'})
        }
      }
      // 增加全局tip 或 全局loading
      return config
    }, error => {
      return Promise.reject(error)
    })

    // 拦截响应
    instance.interceptors.response.use(res => {
      const { data, status, config: { url } } = res
      if (!res.config.hideMessage) {
        let message = '<div>接口路径: ' + url + '</div>'
        if (data && data.hostInfo) {
          message += '<div>处理地址: ' + data.hostInfo.ip + '</div>'
          message += '<div>服务器名: ' + data.hostInfo.name + '</div>'
        }
        Notification.success({
          title: '提示',
          dangerouslyUseHTMLString: true,
          message: message,
          duration: 1500,
          position: 'bottom-right'
        })
      }
      return { data, status }
    }, error => {
      // 吞掉错误
      if (!error || !error.request) {
        console.log('error', error)
        return
      }
      const { request: { statusText, status }, config } = error
      const errorInfo = {
        statusText,
        status,
        request: { responseUrl: config.url }
      }
      delete this.sourceToken[config.url]
      if (errorInfo.status) {
        if (errorInfo.status === 500) {
          Message({
            message: '服务器故障, 请刷新重试',
            type: 'error',
            center: true
          })
        } else if (errorInfo.status === 504) {
          Message({
            message: '网络故障，请刷新重试',
            type: 'error',
            center: true
          })
        }
        // Notification.error(`请求接口${config.url}发生错误，状态: ${status}, 描述: ${statusText}`)
      }
      return null
    })
  }
}

// 请求的默认配置
function getConfig () {
  return {
    headers: {
      token: jsCookie.get('token')
    }
  }
}

const blogAxios = new BlogAxios()
export default blogAxios.request
